package cn.edu.hit;

import cn.edu.hit.CacheManager;
import cn.edu.hit.core.Document;
import cn.edu.hit.core.conf.ConfigureLoader;
import cn.edu.hit.core.db.*;
import cn.edu.hit.kg.data.CypherRunner;
import cn.edu.hit.kg.data.GraphData;
import cn.edu.hit.kg.data.GraphDataProvider;
import cn.edu.hit.kg.data.Node;
import cn.edu.hit.kg.entity.BaseNode;
import cn.edu.hit.kg.entity.Fault;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.context.request.WebRequest;
import redis.clients.jedis.Jedis;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

@RestController
public class Controller {
    static DataConnection connection = DataConnectionLoader.getInstance();
    static DataReader reader = connection.getReader();
    static DBReadHelper dbHelper = new DBReadHelper(reader);
    static GraphData graphData = GraphData.getInstance();

    public static final CacheManager cacheManager = CacheManager.getInstance();

    @Autowired
    HttpServletRequest request;


    /**
     * 用来获取已结束的故障
     *
     * @return
     */
    @CrossOrigin
    @RequestMapping(method = RequestMethod.GET, value = "faults", produces = "application/json;charset=UTF-8")
    public JSONArray loadFaults() {
        Set<String> keys = cacheManager.getJedis().keys("end_fault*");

        JSONArray jarr = new JSONArray();
        for (String key : keys) {
            JSONObject fault = new JSONObject();
            long size = cacheManager.getJedis().llen(key);
            JSONArray jsonArray = new JSONArray();
            for (long i = 0; i < size; i++) {
                String json = cacheManager.getJedis().lindex(key, i);
                JSONObject jobj = JSONObject.fromObject(json);
                String keys2 = "feature_frequency:" + jobj.getString("machineNumber") + ":" + jobj.getInt("feature_id");
                if (cacheManager.getJedis().exists(keys2)) {
                    String json2 = cacheManager.getJedis().get(keys2);
                    JSONObject jobj2 = JSONObject.fromObject(json2);
                    jobj.put("quantum", jobj2.get("quantum"));
                    jobj.put("frequency", jobj2.getJSONObject("frequency").get(jobj.getString("fault_id")));
                }
                jobj.put("properties", graphData.getById(jobj.getInt("feature_id")).asMap());

                jsonArray.add(jobj);
                if (i == 0) {
                    fault.put("properties", graphData.getById(jobj.getInt("fault_id")).asMap());
                    JSONObject reason_pr = this.loadReasonFreq(jobj.getString("machineNumber"), jobj.getInt("fault_id"));
                    List<Map> reasons = graphData.getAllSubNodes(jobj.getInt("fault_id"))
                            .filter(node -> node.hasLabel("Reason"))
                            .map(r -> {
                                JSONObject reason = JSONObject.fromObject(r.asMap());
                                reason.put("id", r.id());
                                return reason;
                            }).collect(Collectors.toList());

                    fault.put("reasons", reasons);
                    fault.put("reasons_probability", reason_pr);
                }
            }
            fault.put("features", jsonArray);
            jarr.add(fault);
        }
        return jarr;
    }

    @CrossOrigin
    @RequestMapping(method = RequestMethod.GET, value = "reason/{machineNumber}/{id}", produces = "application/json;charset=UTF-8")
    public JSONObject loadReasonFreq(@PathVariable("machineNumber") String machineNumber, @PathVariable("id") long fault_id) {
        String freqKey = "fault_reason" + machineNumber + ":" + fault_id;
        JSONObject freq;
//        Jedis jedis = connectJedis();
        if (cacheManager.getJedis().exists(freqKey)) {
            freq = JSONObject.fromObject(cacheManager.getJedis().get(freqKey));
        } else {
//            GraphData graphData = GraphData.getInstance();
            freq = new JSONObject();
            Node fault = graphData.getById(fault_id);
            freq.put("quantum", fault.asMap().getOrDefault("quantum", 100));
            if (fault.asMap().containsKey("frequency")) {
                freq.put("frequency", fault.asMap().get("frequency"));
            } else {
                freq.put("frequency", graphData.getAllSubNodes(fault_id)
                        .filter(node -> StreamSupport.stream(node.labels().spliterator(), false)
                                .anyMatch(x -> x.equals("Reason")))
                        .collect(Collectors.toMap(x -> "" + x.id(), x -> Double.parseDouble(x.asMap().get("probability").toString()) * 100)));
            }
        }
//        jedis.close();
        return freq;
    }
}
